/*********************************************************************************
 *      Copyright:  (C) 2025 ZYT
 *                  All rights reserved.
 *
 *       Filename:  bridge.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(10/08/25)
 *         Author:  ZYT <zhangyuting@163.com>
 *      ChangeLog:  1, Release initial version on "10/08/25 11:19:23"
 *                 
 ********************************************************************************/
#include "bridge.h"
#include "can_comm.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/epoll.h>

// 发送缓冲区：MQTT/LVGL → 单片机
typedef struct 
{
	struct can_frame 	buffer[CAN_BUFFER_SIZE];
	int 				head;
	int					tail;
	int					count;
	pthread_mutex_t 	mutex;
} tx_buffer_t;

// 接收缓冲区：单片机 → MQTT/LVGL（双线程读取）
typedef struct 
{
	struct can_frame 	buffer[CAN_BUFFER_SIZE];
	int 				head;
	int					tail;
	int					count;
	int 				read_ack[CAN_BUFFER_SIZE];  //0:都没读 1: thread1读, 2: thread2读, 3: 都读
	pthread_mutex_t 	mutex;
	pthread_cond_t 		cond1;
	pthread_cond_t		cond2;
	//cond为条件变量，用于同步两个线程的读操作。如果线程尝试读取时缓冲区为空，则它会等待直到有新的CAN帧到达并通知它继续执行。
} rx_buffer_t;

static tx_buffer_t tx_buf = {.head = 0, .tail = 0, .count = 0, .mutex = PTHREAD_MUTEX_INITIALIZER};
static rx_buffer_t rx_buf = {.head = 0, .tail = 0, .count = 0, .mutex = PTHREAD_MUTEX_INITIALIZER};

static pthread_t 	bridge_tid;
static int 			running = 0;
static int 			epoll_fd = -1;

// 桥接线程主函数
static void* bridge_thread(void* arg) 
{
	struct can_frame 	frame;
	struct epoll_event 	ev;//注册监听的事件
	struct epoll_event	events[1];//存储epoll返回的就绪事件
	int 				nfds;
	int					idx;

	ev.events = EPOLLIN;
	ev.data.fd = can_comm_get_socket();
	if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, ev.data.fd, &ev) == -1) 
	{
		perror("epoll_ctl");
		return NULL;
	}

	running = 1;
	printf("[Bridge] Thread running...\n");

	while (running) 
	{
		nfds = epoll_wait(epoll_fd, events, 1, 100);
		if (nfds < 0 && errno != EINTR) 
		{
			perror("epoll_wait");
			continue;
		}

		// 处理 CAN 接收
		if (nfds > 0 && (events[0].events & EPOLLIN)) 
		{
			if (can_comm_receive(&frame) == 0) 
			{
				pthread_mutex_lock(&rx_buf.mutex);
				if (rx_buf.count < CAN_BUFFER_SIZE) 
				{
					idx = rx_buf.tail;
					rx_buf.buffer[idx] = frame;
					rx_buf.read_ack[idx] = 0;
					rx_buf.tail = (rx_buf.tail + 1) % CAN_BUFFER_SIZE;
					rx_buf.count++;
					pthread_cond_signal(&rx_buf.cond1);
					pthread_cond_signal(&rx_buf.cond2);
				} 
				else 
				{
					fprintf(stderr, "[Bridge] RX buffer full!\n");
				}
				pthread_mutex_unlock(&rx_buf.mutex);
			}
		}

		// 尝试发送
		pthread_mutex_lock(&tx_buf.mutex);
		if (tx_buf.count > 0) 
		{
			frame = tx_buf.buffer[tx_buf.head];
			tx_buf.head = (tx_buf.head + 1) % CAN_BUFFER_SIZE;
			tx_buf.count--;
			pthread_mutex_unlock(&tx_buf.mutex);

			if (can_comm_send(&frame) != 0) 
			{
				fprintf(stderr, "[Bridge] Failed to send CAN frame.\n");
			}
		} 
		else 
		{
			pthread_mutex_unlock(&tx_buf.mutex);
		}
	}

	return NULL;
}

// 初始化桥接模块
int bridge_init(void) 
{
	pthread_cond_init(&rx_buf.cond1, NULL);//初始化条件变量cond1
	pthread_cond_init(&rx_buf.cond2, NULL);//初始化条件变量cond2

	epoll_fd = epoll_create1(0);
	if (epoll_fd == -1) 
	{
		perror("epoll_create1");
		return -1;
	}

	if (pthread_create(&bridge_tid, NULL, bridge_thread, NULL) != 0) 
	{
		fprintf(stderr, "[Bridge] Failed to create thread.\n");
		close(epoll_fd);
		return -1;
	}

	return 0;
}

// 发送到 MCU
int thread1_to_bridge(const struct can_frame *frame) 
{
	pthread_mutex_lock(&tx_buf.mutex);
	if (tx_buf.count >= CAN_BUFFER_SIZE) 
	{
		pthread_mutex_unlock(&tx_buf.mutex);
		return -1; // 缓冲区已满
	}
	tx_buf.buffer[tx_buf.tail] = *frame;
	tx_buf.tail = (tx_buf.tail + 1) % CAN_BUFFER_SIZE;
	tx_buf.count++;
	pthread_mutex_unlock(&tx_buf.mutex);
	return 0;
}

// thread1 读取
int bridge_to_thread1(struct can_frame *frame) 
{
	pthread_mutex_lock(&rx_buf.mutex);
	while (rx_buf.count == 0) 
	{
		pthread_cond_wait(&rx_buf.cond1, &rx_buf.mutex);
	}
	*frame = rx_buf.buffer[rx_buf.head];
	rx_buf.read_ack[rx_buf.head] |= 1;
	if (rx_buf.read_ack[rx_buf.head] == 3) 
	{
		rx_buf.head = (rx_buf.head + 1) % CAN_BUFFER_SIZE;
		rx_buf.count--;
	}
	pthread_mutex_unlock(&rx_buf.mutex);
	return 0;
}

// thread2 读取
int bridge_to_thread2(struct can_frame *frame) 
{
	pthread_mutex_lock(&rx_buf.mutex);
	while (rx_buf.count == 0) 
	{
		pthread_cond_wait(&rx_buf.cond2, &rx_buf.mutex);
	}
	*frame = rx_buf.buffer[rx_buf.head];
	rx_buf.read_ack[rx_buf.head] |= 2;
	if (rx_buf.read_ack[rx_buf.head] == 3) 
	{
		rx_buf.head = (rx_buf.head + 1) % CAN_BUFFER_SIZE;
		rx_buf.count--;
	}
	pthread_mutex_unlock(&rx_buf.mutex);
	return 0;
}

// 销毁
void bridge_destroy(void) 
{
	running = 0;
	pthread_join(bridge_tid, NULL);
	close(epoll_fd);
	pthread_cond_destroy(&rx_buf.cond1);
	pthread_cond_destroy(&rx_buf.cond2);
}

